﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;
using storeProcedure;

namespace Player
{
    namespace MyAttribute
    {

        [AttributeUsage(AttributeTargets.Field)]
        public class InputMappingAttribute : Attribute
        {
            private int m_variable;

            public InputMappingAttribute(int variable)
            {
                m_variable = variable;
            }

            public int Variable
            {
                get { return m_variable; }
            }
        }

        [AttributeUsage(AttributeTargets.Field)]
        public class OutputMappingAttribute : Attribute
        {
            private int m_variable;
            private SqlDbType m_dbType;
            private int m_size;

            public OutputMappingAttribute(int variable, SqlDbType dbType)
            {
                m_variable = variable;
                m_dbType = dbType;
            }

            public OutputMappingAttribute(int variable, SqlDbType dbType, int size)
            {
                m_variable = variable;
                m_dbType = dbType;
                m_size = size;
            }

            public int Variable
            {
                get { return m_variable; }
            }

            public SqlDbType DbType
            {
                get { return m_dbType; }
            }

            public int Size
            {
                get { return m_size; }
            }
        }

        [AttributeUsage(AttributeTargets.Field)]
        public class ColumnMappingAttribute : Attribute
        {
            private Type m_table;
            private int m_column;

            public ColumnMappingAttribute()
            {
            }

            public ColumnMappingAttribute(Type table, int column)
            {
                m_table = table;
                m_column = column;
            }

            public string Name
            {
                get
                {
                    string prefix = null;

                    TableAttribute attr = Attribute.GetCustomAttribute(m_table, typeof(TableAttribute)) as TableAttribute;
                    if (attr != null) prefix = attr.Name;

                    ViewAttribute vattr = Attribute.GetCustomAttribute(m_table, typeof(ViewAttribute)) as ViewAttribute;
                    if (vattr != null) prefix = vattr.Name;

                    if (prefix == null) throw new Exception("Table name is not defined.  Please use TableAttribute to define the table name");

                    foreach (FieldInfo fi in m_table.GetFields(BindingFlags.Public | BindingFlags.Static))
                    {
                        if ((int)fi.GetRawConstantValue() == m_column)
                        {
                            return "[" + prefix + "].[" + fi.Name + "]";
                        }
                    }

                    throw new Exception("Unknown column mapped by ColumnMappingAttribute");
                }
            }
        }

        [AttributeUsage(AttributeTargets.Enum)]
        public class ViewAttribute : Attribute
        {
            private string m_name;
            private bool m_suppressCreation;

            public string Name
            {
                get { return m_name; }
            }

            public ViewAttribute(string name)
            {
                m_name = name;
            }

            public ViewAttribute(string name, bool suppressCreation)
            {
                m_name = name;
                m_suppressCreation = suppressCreation;
            }
        }

        [AttributeUsage(AttributeTargets.Field)]
        public class ColumnAttribute : Attribute
        {
            private SqlDbType m_type;
            private int? m_maxLength;
            private bool m_isNullable;
            private bool m_isIdentity;
            private Type m_foreignTable;
            private int m_foreignKey;

            public ColumnAttribute(SqlDbType type)
                : this(type, false)
            {
                m_maxLength = null;
            }

            public ColumnAttribute(SqlDbType type, bool isNullable)
            {
                m_type = type;
                m_maxLength = null;
                m_isNullable = isNullable;
                m_isIdentity = false;
            }

            public ColumnAttribute(SqlDbType type, bool isNullable, bool isIdentity)
            {
                m_type = type;
                m_maxLength = null;
                m_isNullable = isNullable;
                m_isIdentity = isIdentity;
            }

            public ColumnAttribute(SqlDbType type, bool isNullable, bool isIdentity, Type foreignTable, int foreignKey)
                : this(type, isNullable, isIdentity)
            {
                m_foreignTable = foreignTable;
                m_foreignKey = foreignKey;
            }

            public ColumnAttribute(SqlDbType type, int maxLength)
                : this(type, maxLength, false)
            {
            }

            public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable)
            {
                m_type = type;
                m_maxLength = maxLength;
                m_isNullable = isNullable;
                m_isIdentity = false;
            }

            public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable, bool isIdentity)
            {
                m_type = type;
                m_maxLength = maxLength;
                m_isNullable = isNullable;
                m_isIdentity = isIdentity;
            }

            public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable, bool isIdentity, Type foreignTable, int foreignKey)
                : this(type, maxLength, isNullable, isIdentity)
            {
                m_foreignTable = foreignTable;
                m_foreignKey = foreignKey;
            }

            public SqlDbType Type
            {
                get
                {
                    return m_type;
                }
            }

            public int? MaxLength
            {
                get
                {
                    return m_maxLength;
                }
            }

            public bool IsNullable
            {
                get
                {
                    return m_isNullable;
                }
            }

            public bool IsIdentity
            {
                get
                {
                    return m_isIdentity;
                }
            }

            public Type ForeignTable
            {
                get { return m_foreignTable; }
            }

            public int ForeignKey
            {
                get { return m_foreignKey; }
            }
        }

        [AttributeUsage(AttributeTargets.Enum)]
        public class TableAttribute : Attribute
        {
            private string m_name;
            private bool m_suppressCreation;

            public TableAttribute(string name)
            {
                m_name = name;
            }

            public TableAttribute(string name, bool suppressCreation)
            {
                m_name = name;
                m_suppressCreation = suppressCreation;
            }

            public string Name
            {
                get { return m_name; }
            }

            public bool SuppressCreation
            {
                get { return m_suppressCreation; }
            }
        }

        [AttributeUsage(AttributeTargets.Field)]
        public class VariableAttribute : Attribute
        {
            private Direction m_direction;

            public VariableAttribute(Direction direction)
            {
                m_direction = direction;
            }

            public Direction Direction
            {
                get { return m_direction; }
            }
        }

        [AttributeUsage(AttributeTargets.Field)]
        public class PropertyAttribute : Attribute
        {
            private SqlDbType m_type;
            private int? m_maxLength;

            public PropertyAttribute(SqlDbType type)
            {
                m_type = type;
                m_maxLength = null;
            }

            public PropertyAttribute(SqlDbType type, int maxLength)
            {
                m_type = type;
                m_maxLength = maxLength;
            }

            public SqlDbType Type
            {
                get
                {
                    return m_type;
                }
            }

            public int? MaxLength
            {
                get
                {
                    return m_maxLength;
                }
            }
        }

        [AttributeUsage(AttributeTargets.Enum)]
        public class UniqueConstraintAttribute : Attribute
        {
            private int[] m_columns;
            public UniqueConstraintAttribute(int[] columns)
            {
                m_columns = columns;
            }

            public IList<int> Columns
            {
                get
                {
                    return m_columns;
                }
            }
        }

        [AttributeUsage(AttributeTargets.Enum)]
        public class PrimaryConstraintAttribute : Attribute
        {
            private int[] m_columns;
            public PrimaryConstraintAttribute(int[] columns)
            {
                m_columns = columns;
            }

            public IList<int> Columns
            {
                get
                {
                    return m_columns;
                }
            }
        }
    }
}